#!/usr/bin/env python

'''
cmdtutor provides the mechanism to 'execute' command line tutorials written
in a standard format. It acts as an interface between the user and the 
terminal.

Author: Raja (rajajs@gmail.com)
Version: 0.2, 6 Mar 2007
version 0.3, 24 Mar 2007 - added quickflag
             04 Apr 2007 - added wrapping            
'''

import commands, os, sys, time, readline, textwrap, shutil

def printhelp():
    print ""
    print "cmd_tutor version 0.3"
    print "An interactive tutorial for the unix command line"
    print ""
    print "Usage: cmd_tutor [OPTION]"
    print ""
    print "Options"
    print "-h    Display this help"
    print "-q    No slow printing of instructions"
    print ""
    print "Type 'quit' anytime during lesson to quit"
    print ""
    print "Comments and suggestions to Raja S. <rajajs@gmail.com>"
    
def slowprint(text,pause):
    words = text.split()
    for i in range(len(words)-1):
        print words[i],
        sys.stdout.flush()
        time.sleep(pause)
    print words[-1] #no comma after the last word so that it wraps   

def getColorcodes():
    code = dict()
    code['BOLD'] = os.popen("tput bold").read()
    code['NOBOLD'] = os.popen("tput sgr0").read()
    code['RED'] = os.popen("tput setaf 1").read()
    code['NORMAL'] = os.popen("tput setaf 9").read()
    return code

def blockParse(block):
    chunks = block.split(':')
    instruction = chunks[1].rstrip('Error')
    error = chunks[2].rstrip('Next')
    next = chunks[3]
    return (instruction,error,next)

pause = 0.2

if len(sys.argv) > 1:
    if sys.argv[1] == '-q':
        pause = 0
    elif sys.argv[1] == '-h':
        printhelp()
        sys.exit()
    else:
        pass         
    
homedir = commands.getoutput('echo $HOME')
code = getColorcodes()
termwidth = int(commands.getoutput('echo $COLUMNS'))

lessonsPath =  '/usr/share/cmd_tutor/lessons'
while not os.path.exists(lessonsPath):
    lessonsPath = raw_input\
    ("Please enter the location of the lessons eg. /home/lessons >>")
lessons = os.listdir(lessonsPath)
lessons.sort()

testfolderPath = lessonsPath.rstrip('lessons') + 'cmd_test'
tmptestfolder = homedir+ '/Desktop/cmd_test'
if os.path.exists(tmptestfolder):
    while os.path.exists(tmptestfolder):
        tmptestfolder = tmptestfolder+ '1'
    print "-"*40
    print "A folder called cmd_test already existed on the desktop."
    print "Therefore the test folder will be named ",tmptestfolder

shutil.copytree(testfolderPath,tmptestfolder )
os.chdir(tmptestfolder)

print "-"*40
print "-"*40
print "Linux command line tutorial"
print "-"*40
print "-"*40
print ""

if len(lessons) == 0:
    print "There are no lessons in the directory"
    sys.exit()
elif len(lessons) == 1:
    print lessons[0]+ ' found. Starting lesson'
    thisLesson = lessons[0]
else:
    print "The following lessons are found. Enter name of lesson to start"
    
    for eachlesson in lessons:
        print eachlesson
    print ""
    thisLesson = 'nolessonbythisname'
    while thisLesson not in lessons:
        thisLesson = raw_input()

fi = open(lessonsPath+ '/' +thisLesson,'r')
print "Type 'quit' to quit the tutorial at any time"
#mainloop
line = ''
status = 0

while line <> 'end':
    line = ''
    block = ''
    command = 'resetcommand'
    while line <> '%%':
        line = fi.readline().rstrip('\n')
        block += line
            
    (instruction,error,next) = blockParse(block.rstrip('%%\n'))
    
    print ''
    print '-'*termwidth
    instr = instruction.replace('[',code['RED']).replace(']',code['NORMAL'])
    for eachline in textwrap.wrap(instr,termwidth):
        slowprint(eachline,pause)
                
    while not eval(next.replace('command','command.split(' ')')\
                   .replace('output','commands.getoutput')) or status <> 0:
    
        print code['BOLD']
        #print ''
        command  = raw_input('Tutor>>> ')
        print code['NOBOLD']+ ''
        
        if command == 'quit':
            shutil.rmtree(tmptestfolder)
            fi.close()
            sys.exit()
        if command[:2] == 'cd':
            targetdir = command.lstrip('cd ').replace('~',homedir)
            if os.path.isdir(targetdir):
                os.chdir(targetdir)
                status = 0
            else:
                status = 1
        else:
            status = os.system(command)
        if status <> 0:
            if len(error) > 0:
                slowprint(error.replace('[',code['RED']).replace(']',\
                code['NORMAL']),pause)
            else:
                slowprint("Check if you typed the command correctly",pause)    
            
fi.close()
